#include "led.h" // 包含自己的头文件
// 如果你的STM32固件库组织方式不同，可能还需要在这里包含特定的GPIO和RCC库文件
// 例如：#include "stm32f10x_rcc.h" 和 #include "stm32f10x_gpio.h"
#include "SysTick.h"

LED_Config_TypeDef myLEDs[] = {
    {GPIOE, GPIO_Pin_7},
    {GPIOE, GPIO_Pin_6},
    {GPIOE, GPIO_Pin_5},
    {GPIOE, GPIO_Pin_4},
    {GPIOE, GPIO_Pin_3},
    {GPIOE, GPIO_Pin_2},
    {GPIOE, GPIO_Pin_1},
    {GPIOE, GPIO_Pin_0},
};

/**
 * @brief  初始化指定GPIO引脚为推挽输出模式，并设置其初始状态。
 * @param  GPIOx: GPIO组，例如GPIOA, GPIOB, GPIOC, 等。
 * @param  GPIO_Pin: 要初始化的引脚，例如GPIO_Pin_0, GPIO_Pin_1, 等。
 * @param  initialState: 初始状态，可以是Bit_RESET (低电平) 或 Bit_SET (高电平)。
 * @retval 无
 */
void LED_GPIO_Init(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, BitAction initialState)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // 1. 开启GPIO端口时钟
    // 这是一个switch-case或者if-else if结构，用于根据传入的GPIOx开启对应的时钟
    if (GPIOx == GPIOA)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    }
    else if (GPIOx == GPIOB)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    }
    else if (GPIOx == GPIOC)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    }
    else if (GPIOx == GPIOD)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
    }
    else if (GPIOx == GPIOE)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
    }
    // 根据你的STM32型号和实际设计，可能还需要添加GPIOF, GPIOG等
    /*
    else if (GPIOx == GPIOF)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
    }
    else if (GPIOx == GPIOG)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);
    }
    */

    // 2. 配置GPIO结构体
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin;           // 要配置的引脚
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 输出速度
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  // 推挽输出模式

    // 3. 初始化GPIO引脚
    GPIO_Init(GPIOx, &GPIO_InitStructure);

    // 4. 设置引脚的初始状态
    // 注意：这里的initialState是引脚的电平，而不是LED的亮灭。
    // 亮灭取决于LED的接法（共阴或共阳）。
    if (initialState == Bit_SET)
    {
        GPIO_SetBits(GPIOx, GPIO_Pin);
    }
    else
    {
        GPIO_ResetBits(GPIOx, GPIO_Pin);
    }
}

/**
 * @brief  翻转指定LED引脚的状态（亮变灭，灭变亮）。
 *         此函数会读取当前引脚的输出状态并翻转它。
 * @param  GPIOx: LED所在的GPIO组。
 * @param  GPIO_Pin: LED引脚。
 * @retval 无
 */
void LED_Toggle(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
    // GPIO_ReadOutputDataBit 函数读取的是输出数据寄存器的当前值
    if (GPIO_ReadOutputDataBit(GPIOx, GPIO_Pin) == Bit_SET)
    {
        GPIO_ResetBits(GPIOx, GPIO_Pin); // 如果当前是高，则拉低
    }
    else
    {
        GPIO_SetBits(GPIOx, GPIO_Pin); // 如果当前是低，则拉高
    }
}

/**
 * @brief  点亮指定LED。
 *         默认假设LED为共阴极接法（高电平点亮）。
 *         示例：如果你的LED负极接地，正极连接到GPIO引脚，则高电平时LED亮。
 * @param  GPIOx: LED所在的GPIO组。
 * @param  GPIO_Pin: LED引脚。
 * @retval 无
 */
void LED_On(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
    // 对于共阴极LED，高电平使得其导通点亮
    GPIO_SetBits(GPIOx, GPIO_Pin);
}

/**
 * @brief  熄灭指定LED。
 *         默认假设LED为共阴极接法（低电平熄灭）。
 *         示例：如果你的LED负极接地，正极连接到GPIO引脚，则低电平时LED灭。
 * @param  GPIOx: LED所在的GPIO组。
 * @param  GPIO_Pin: LED引脚。
 * @retval 无
 */
void LED_Off(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
    // 对于共阴极LED，低电平使得其截止熄灭
    GPIO_ResetBits(GPIOx, GPIO_Pin);
}

/**
 * @brief led数组初始化
 * @param  void 无
 * @retval 无
 */
void LEDS_GPIO_Init(void)
{

    uint8_t numLEDs = sizeof(myLEDs) / sizeof(myLEDs[0]);

    // 初始化所有LED引脚
    for (uint8_t i = 0; i < numLEDs; i++)
    {
        // 将所有LED初始化为低电平（熄灭）

        LED_GPIO_Init(myLEDs[i].GPIOx, myLEDs[i].GPIO_Pin, Bit_SET); //   Bit_RESET (低电平) 或 Bit_SET (高电平)。
    }
		
		
}

void LEDS_off(void)
{

    uint8_t numLEDs = sizeof(myLEDs) / sizeof(myLEDs[0]);

    // 初始化所有LED引脚
    for (uint8_t i = 0; i < numLEDs; i++)
    {
        // 将所有LED初始化为低电平（熄灭）
        LED_GPIO_Init(myLEDs[i].GPIOx, myLEDs[i].GPIO_Pin, Bit_SET); //   Bit_RESET (低电平) 或 Bit_SET (高电平)。
    }
}

/**
 * @brief 跑马灯
 * @param  void 无
 * @retval 无
 * */
void LEDS_Runs(void)
{

    LEDS_off();
     uint8_t numLEDs = sizeof(myLEDs) / sizeof(myLEDs[0]);
    for (uint8_t i = 0; i < numLEDs; i++)
    {

        LED_Off(myLEDs[i].GPIOx, myLEDs[i].GPIO_Pin); //            Delay_ms(500);
        // delay_xms(100);
         delay_ms(50);
        LED_On(myLEDs[i].GPIOx, myLEDs[i].GPIO_Pin);
        // delay_xms(100);
         delay_ms(50);
    }
}
